Skip to content

fix untagged enum automatic ordering#991

Open
Farossco wants to merge 1 commit intooxidecomputer:mainfrom
Farossco:fares/reordered_untagged_enum
Open

fix untagged enum automatic ordering#991
Farossco wants to merge 1 commit intooxidecomputer:mainfrom
Farossco:fares/reordered_untagged_enum

Conversation

@Farossco
Copy link

@Farossco Farossco commented Mar 5, 2026

When parsing the following type of schema definition:

{
    "definitions": {
        "Value": {
            "type": [
                "array",
                "boolean",
                "integer",
                "number",
                "object",
                "string"
            ]
        }
    }
}

The following rust type is generated:

pub enum Value {
    Boolean(bool),
    Object(::serde_json::Map<::std::string::String, ::serde_json::Value>),
    Array(::std::vec::Vec<::serde_json::Value>),
    Number(f64),
    String(::std::string::String),
    Integer(i64),
}

This is mostly what we want but the issue here is the ordering. The use of a BTreeMap not only deduplicates but also re-orders the types to follow the ordering of the InstanceType enum from schemars which puts the Number type before the Integer type.

This makes the Integer variant of our Value enum here unreachable as all possible values can already be matched by the Number variant.

I believe that forcing the re-ordering of the variant instead of following the ordering declared in the schema is a good thing but it should be slightly tweaked.

This PR introduces an intermediate re-definition of this InstanceType enum with re-ordered fields and uses it for this BTreeMap deduplication.

This in terms, gives us the following rust enum definition:

pub enum Value {
    Boolean(bool),
    Integer(i64),
    Number(f64),
    String(::std::string::String),
    Array(::std::vec::Vec<::serde_json::Value>),
    Object(::serde_json::Map<::std::string::String, ::serde_json::Value>),
}

@Farossco Farossco force-pushed the fares/reordered_untagged_enum branch 3 times, most recently from e446496 to 5da50fb Compare March 5, 2026 14:01
Signed-off-by: Farès Chati <fchati@smartandconnective.com>
@Farossco Farossco force-pushed the fares/reordered_untagged_enum branch from 5da50fb to a79bf15 Compare March 5, 2026 14:02
@Farossco Farossco changed the title re-order untagged enum fix untagged enum automatic ordering Mar 11, 2026
ndreno added a commit to barbacane-dev/typify that referenced this pull request Mar 19, 2026
Cherry-picked from upstream PR oxidecomputer#991. When a schema defines an untagged
enum with both integer and number types, serde tries variants in order.
Having Number (f64) before Integer (i64) made the Integer variant
unreachable since any integer is also a valid f64.

Introduces ReorderedInstanceType to ensure Integer is always matched
before Number during deserialization.
ndreno added a commit to barbacane-dev/typify that referenced this pull request Mar 19, 2026
18 new runtime tests verifying actual serde behavior, not just codegen:

- PR oxidecomputer#991: IntOrStr deserializes 42 as Integer (not swallowed by Number)
- PR oxidecomputer#918: RequiredWithDefaults::default() has correct values;
  deserializing {} uses schema defaults
- PR oxidecomputer#986: Dscp TryFrom rejects 64, accepts 0-63; serde rejects
  out-of-range JSON values
- PR oxidecomputer#948: All 9 comparator symbols round-trip through serde correctly
- PR oxidecomputer#414: anyOf with object+string+integer deserializes without panic
- PR oxidecomputer#954: not:{type:"object"} accepts primitives; array items work

Also fixes pre-existing CustomMap test compilation (missing Default
and is_empty) and adds serde derive feature to typify-test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant